package com.csw.android.ffmpegtest.ui.section6

import android.content.res.AssetManager
import android.graphics.BitmapFactory
import android.opengl.GLSurfaceView
import android.os.Bundle
import android.view.View
import com.csw.android.ffmpegtest.R
import com.csw.android.ffmpegtest.app.MyApplication
import com.csw.android.ffmpegtest.databinding.LayoutSection501Binding
import com.csw.android.ffmpegtest.gl.Section601Renderer
import com.csw.android.ffmpegtest.ui.base.DataBindingFragment
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import java.io.FileNotFoundException
import java.util.concurrent.TimeUnit

/**
 * 学习 Android 平台 OpenGL ES API，学习纹理绘制，能够使用 OpenGL 显示一张图片
 */
class Section601 : DataBindingFragment<LayoutSection501Binding>() {
    private var disposable: Disposable? = null
    private var renderer: Section601Renderer? = null

    override fun getContentViewID(): Int {
        return R.layout.layout_section_501
    }

    override fun initView(rootView: View, savedInstanceState: Bundle?) {
        super.initView(rootView, savedInstanceState)
        dataBinding?.glSurfaceView?.run {
            setEGLContextClientVersion(3)
            setRenderer(Section601Renderer().also {
                renderer = it
            })
            //设置为数据更改时刷新，通过requestRender()进行刷新
            renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY
        }
    }

    init {
        disposable?.dispose()
        disposable = Observable.interval(0, 1, TimeUnit.SECONDS)
            .observeOn(Schedulers.io())
            .map {
                val bitmap = when (it % 4) {
                    0L -> {
                        BitmapFactory.decodeStream(
                            MyApplication.instance.resources.assets.open(
                                "test.bmp",
                                AssetManager.ACCESS_UNKNOWN
                            )
                        )
                    }
                    1L -> {
                        BitmapFactory.decodeResource(
                            MyApplication.instance.resources,
                            R.drawable.benxi2
                        )
                    }
                    2L -> {
                        BitmapFactory.decodeResource(
                            MyApplication.instance.resources,
                            R.drawable.benxi
                        )
                    }
                    else -> {
                        BitmapFactory.decodeResource(
                            MyApplication.instance.resources,
                            R.drawable.benxi1
                        )
                    }
                }
                if (bitmap != null) {
                    try {
                        val w = bitmap.width
                        val h = bitmap.height
                        val pixels = IntArray(w * h)
                        bitmap.getPixels(pixels, 0, w, 0, 0, w, h)
                        val rgbByteArray = ByteArray(pixels.size * 3)
                        var p: Int
                        for (i in pixels.indices) {
                            p = pixels[i]
                            rgbByteArray[i * 3 + 0] = p.shr(16).and(0xff).toByte()
                            rgbByteArray[i * 3 + 1] = p.shr(8).and(0xff).toByte()
                            rgbByteArray[i * 3 + 2] = p.and(0xff).toByte()
                        }
                        return@map RGBData(w, h, rgbByteArray)
                    } catch (e: Exception) {
                        throw e
                    } finally {
                        bitmap.recycle()
                    }
                } else {
                    throw FileNotFoundException("图片未找到")
                }
            }
//            .observeOn(AndroidSchedulers.mainThread())//跑子线程也没关系
            .subscribe(
                {
                    renderer?.updatePicture(it.w, it.h, it.data)
                    dataBinding?.glSurfaceView?.requestRender()
                }, {
                    it.printStackTrace()
                }
            )
    }

    override fun onResume() {
        super.onResume()
        dataBinding?.glSurfaceView?.onResume()
    }

    override fun onPause() {
        dataBinding?.glSurfaceView?.onPause()
        super.onPause()
    }

    override fun onDestroyView() {
        renderer = null
        disposable?.dispose()
        disposable = null
        super.onDestroyView()
    }

    private class RGBData(val w: Int, val h: Int, val data: ByteArray)
}